﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Data;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System.Reflection;

namespace Cms.EntLib
{
    public class Utiltiy
    {
        /// <summary>
        /// object型转换为bool型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的bool类型结果</returns>
        public static bool StrToBool(object expression, bool defValue)
        {
            return TypeParse.StrToBool(expression, defValue);
        }

        /// <summary>
        /// string型转换为bool型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的bool类型结果</returns>
        public static bool StrToBool(string expression, bool defValue)
        {
            return TypeParse.StrToBool(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        /// <param name="expression">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static int StrToInt(object expression, int defValue)
        {
            return TypeParse.StrToInt(expression, defValue);
        }

        /// <summary>
        /// 将字符串转换为Int32类型
        /// </summary>
        /// <param name="expression">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static int StrToInt(string expression, int defValue)
        {
            return TypeParse.StrToInt(expression, defValue);
        }

        /// <summary>
        /// Object型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static float StrToFloat(object strValue, float defValue)
        {
            return TypeParse.StrToFloat(strValue, defValue);
        }

        /// <summary>
        /// string型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static float StrToFloat(string strValue, float defValue)
        {
            return TypeParse.StrToFloat(strValue, defValue);
        }

        /// <summary>
        /// 判断给定的字符串数组(strNumber)中的数据是不是都为数值型
        /// </summary>
        /// <param name="strNumber">要确认的字符串数组</param>
        /// <returns>是则返加true 不是则返回 false</returns>
        public static bool IsNumericArray(string[] strNumber)
        {
            return TypeParse.IsNumericArray(strNumber);
        }
        /// <summary>
        /// 将网页中非法和有攻击性的符号替换掉，以防sql注入！返回正常数据
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static String StringHelper(String text)
        {
            if (string.IsNullOrEmpty(text))
                return string.Empty;
            text = text.Trim();
            text = Regex.Replace(text, "[\\s]{2,}", " ");	// 2个或以上的空格
            text = Regex.Replace(text, "(<[b|B][r|R]/*>)+|(<[p|P](.|\\n)*?>)", "\n");	//<br> html换行符
            text = Regex.Replace(text, "(\\s*&[n|N][b|B][s|S][p|P];\\s*)+", " ");	//&nbsp;   html空格符
            text = Regex.Replace(text, "<(.|\\n)*?>", string.Empty);	// 任何其他的标签
            text = text.Replace("'", "''");// 单引号
            return text;
        }

        public static string StringReplace(bool ishtml, string text, string reg)
        {
            if (ishtml)
            {
                text = text.Trim();
                text = Regex.Replace(text, "\r\n", "");
                text = Regex.Replace(text, "(\\s*&[n|N][b|B][s|S][p|P];\\s*)+", string.Empty);	//&nbsp;   html空格符
                if (!string.IsNullOrEmpty(reg))
                    text = text.Replace(reg, string.Empty);
            }
            else
            {
                if (string.IsNullOrEmpty(text))
                    return string.Empty;
                else
                    text = StringHelper(text).Replace(reg, string.Empty);
            }
            return text;
        }




        /// <summary>
        /// 获取控件的子节点的文本值
        /// </summary>
        /// <param name="xnControl"></param>
        /// <param name="ChildName"></param>
        /// <returns></returns>
        public static string GetXmlChildText(XmlNode xnControl, string ChildName)
        {
            string Result = "";
            if (xnControl != null && xnControl.ChildNodes.Count > 0)
            {
                XmlNode xn = xnControl.SelectSingleNode(ChildName);
                if (xn != null)
                {
                    Result = xn.InnerText;
                }
            }
            return Result;
        }
        public static XmlNodeList GetXmlChildList(XmlNode xnControl, string ChildNames)
        {
            return xnControl == null ? null : xnControl.SelectNodes(ChildNames);
        }

        public static string GetXmlAttribute(XmlNode xn, string attribute)
        {
            string result = "";
            if (xn.Attributes[attribute] != null)
                result = xn.Attributes[attribute].Value;
            return result;
        }

        /// <summary>
        /// 字符串转化为布尔类型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool StringToBool(string str)
        {
            bool result = false;
            switch (str.ToLower())
            {
                case "true":
                case "1":
                case "on":
                case "yes":
                case "checked":
                    result = true;
                    break;
                case "false":
                case "":
                case "0":
                case "off":
                case "no":
                    result = false;
                    break;
                default:
                    result = false;
                    break;
            }
            return result;
        }
        /// <summary>
        /// 转换类型.如果转换失败则将返回该类型的默认值.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static object ConvertToType(object str, Type t)
        {
            object obj = null;
            Type TrueType = t;
            if (t.GetGenericArguments().Length > 0)
                TrueType = t.GetGenericArguments()[0];
            try
            {
                if (TrueType == typeof(bool))
                    obj = StringToBool(str.ToString());
                else if (TrueType.IsEnum)
                {
                    obj = Enum.Parse(TrueType, str.ToString(), true);
                }
                else
                    obj = Convert.ChangeType(str, TrueType);
            }
            catch (Exception e)
            {
                obj = Activator.CreateInstance(TrueType);
                LogHelper.GetInstance().Error("类型转换异常,将转换为默认值", e);
            }

            return obj;
        }
        /// <summary>
        /// 获取系统所有类型.
        /// </summary>
        /// <returns></returns>
        public static List<string> GetDataType()
        {
            List<string> list = new List<string>();
            foreach (System.Reflection.FieldInfo fi in typeof(DbType).GetFields())
            {
                if (fi.Name == "value__")
                    continue;
                list.Add(fi.Name);
            }
            return list;
        }
        public static string BuildAjaxMessage(Enums.MessageType messageType, string MessageBody)
        {
            return "{" + String.Format("status:\"{0}\",msg:\"{1}\"", messageType.ToString().ToLower(), MessageBody) + "}";
        }

        private static string Key = "HANDBAIK";//加密密钥必须为8位  
        //加密算法  
        public static string MD5Encrypt(string pToEncrypt)
        {
            if (String.IsNullOrEmpty(pToEncrypt))
                return "";
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
            des.Key = ASCIIEncoding.ASCII.GetBytes(Key);
            des.IV = ASCIIEncoding.ASCII.GetBytes(Key);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }
        //解密算法  
        public static string MD5Decrypt(string pToDecrypt)
        {
            if (String.IsNullOrEmpty(pToDecrypt))
                return "";
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
            for (int x = 0; x < pToDecrypt.Length / 2; x++)
            {
                int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                inputByteArray[x] = (byte)i;
            }
            des.Key = ASCIIEncoding.ASCII.GetBytes(Key);
            des.IV = ASCIIEncoding.ASCII.GetBytes(Key);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            return System.Text.Encoding.ASCII.GetString(ms.ToArray());
        }

        public static string Escape(string str)
        {
            return Microsoft.JScript.GlobalObject.escape(str);
        }
        public static string UnEscape(string str)
        {
            return Microsoft.JScript.GlobalObject.unescape(str);
        }
        public static string GetHttpData(string url)
        {
            if (!url.ToLower().StartsWith("http://"))
                url = "http://" + url;
            string htmlCode;
            HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
            webRequest.Timeout = 30000;
            webRequest.Method = "GET";
            webRequest.UserAgent = "Mozilla/4.0";
            webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
            HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse();
            if (webResponse.ContentEncoding.ToLower() == "gzip")//如果使用了GZip则先解压
            {               
                using (System.IO.Stream streamReceive = webResponse.GetResponseStream())
                {
                    using (var zipStream =
                        new System.IO.Compression.GZipStream(streamReceive, System.IO.Compression.CompressionMode.Decompress))
                    {
                        using (StreamReader sr = new System.IO.StreamReader(zipStream, Encoding.Default))
                        {
                            htmlCode = sr.ReadToEnd();
                        }
                    }
                }
            }
            else
            {
                using (System.IO.Stream streamReceive = webResponse.GetResponseStream())
                {
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(streamReceive, Encoding.Default))
                    {
                        htmlCode = sr.ReadToEnd();
                    }
                }
            }

            return htmlCode;
        }

        public static object DictToModel(System.Collections.Specialized.NameValueCollection DictMain, Type modelType)
        {
            object objModel = Activator.CreateInstance(modelType);
            foreach (PropertyInfo pi in modelType.GetProperties())
            {
                string pname = "";
                if (!String.IsNullOrEmpty(DictMain[pi.Name]))
                {
                    pname = pi.Name;
                }
                else if (!String.IsNullOrEmpty(DictMain[pi.Name.ToUpper()]))
                {
                    pname = pi.Name.ToUpper();
                }
                if (!String.IsNullOrEmpty(pname))
                {
                    switch (pi.PropertyType.Namespace)
                    {
                        case "System.Collections.Generic"://"Iesi.Collections.Generic":
                        case "Iesi.Collections.Generic":
                            string detailInfo = DictMain[pname];
                            List<Dictionary<string, object>> detailDict = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(detailInfo);
                            if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() != typeof(Nullable<>))
                            {
                                if (pi.PropertyType.GetGenericArguments().Length > 0)
                                {
                                    Type detailType = pi.PropertyType.GetGenericArguments()[0];
                                    //根据泛型类型进行反射创建对象.
                                    object DetailList = pi.GetValue(objModel, null);//Activator.CreateInstance(pi.PropertyType);
                                    foreach (object dk in detailDict)
                                    {
                                        Dictionary<string, object> detailRow = (Dictionary<string, object>)dk;
                                        object objModelDetail = Activator.CreateInstance(detailType);
                                        foreach (PropertyInfo dpi in detailType.GetProperties())
                                        {
                                            string dpname = detailRow.ContainsKey(dpi.Name) ? dpi.Name : (detailRow.ContainsKey(dpi.Name.ToUpper()) ? dpi.Name.ToUpper() : "");
                                            if (!String.IsNullOrEmpty(dpname))
                                            {
                                                object obj = Cms.EntLib.Utiltiy.ConvertToType(detailRow[dpname], dpi.PropertyType);
                                                dpi.SetValue(objModelDetail, obj, null);
                                            }
                                            else
                                            {
                                                if (dpi.PropertyType == modelType)
                                                {
                                                    dpi.SetValue(objModelDetail, objModel, null);
                                                }
                                            }
                                        }
                                        pi.PropertyType.GetMethod("Add").Invoke(DetailList, new object[] { objModelDetail });
                                    }
                                    pi.SetValue(objModel, DetailList, null);
                                }
                            }
                            break;
                        default:
                            object objdefault = Cms.EntLib.Utiltiy.ConvertToType(DictMain[pname], pi.PropertyType);
                            pi.SetValue(objModel, objdefault, null);
                            break;
                    }
                }
            }
            return objModel;
        }
    }
}
